﻿using Microsoft.Win32;    
using System;  
using System.Collections;  
using System.Collections.Generic;  
using System.IO;  
using System.IO.Ports;  
using System.Linq;
using System.Windows.Controls;
using System.Security.Permissions;  
using System.Text;  
using System.Threading;  
using System.Windows;  
using System.Windows.Data; 
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media; 
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation; 
using System.Windows.Media.Imaging;  
using System.Windows.Navigation;  
using System.Windows.Shapes;  
using System.Windows.Threading;
using Visifire.Charts;



namespace 小试牛刀的程序
{
       
    public class customer//各下拉控件访问接口  
    {

        public string com { get; set; }//可用串口  
        public string com1 { get; set; }//可用串口  
        public string BaudRate { get; set; }//波特率  
        public string Parity { get; set; }//校验位  
        public string ParityValue { get; set; }//校验位对应值  
        public string Dbits { get; set; }//数据位  
        public string Sbits { get; set; }//停止位  


    }  
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window  
    {  
        SerialPort ComPort = new SerialPort();//声明一个串口        
        private string[] ports;//可用串口数组  
        private bool recStaus = true;//接收状态字  
        private bool ComPortIsOpen = false;//COM口开启状态字，在打开/关闭串口中使用，这里没有使用自带的ComPort.IsOpen，因为在串口突然丢失的时候，ComPort.IsOpen会自动false，逻辑混乱  
        private bool Listening = false;//用于检测是否没有执行完invoke相关操作，仅在单线程收发使用，但是在公共代码区有相关设置，所以未用#define隔离  
        private bool WaitClose = false;//invoke里判断是否正在关闭串口是否正在关闭串口，执行Application.DoEvents，并阻止再次invoke ,解决关闭串口时，程序假死，具体参见http://news.ccidnet.com/art/32859/20100524/2067861_4.html 仅在单线程收发使用，但是在公共代码区有相关设置，所以未用#define隔离  
        IList<customer> comList = new List<customer>();//可用串口集合  
        DispatcherTimer autoSendTick = new DispatcherTimer();//定时发送  
        private static bool Sending = false;//正在发送数据状态字  
        private static Thread _ComSend;//发送数据线程 

        
        Queue recQueue = new Queue();//接收数据过程中，接收数据线程与数据处理线程直接传递的队列，先进先出  
        private  SendSetStr SendSet = new SendSetStr();//发送数据线程传递参数的结构体  

        
        private  struct SendSetStr//发送数据线程传递参数的结构体格式  
        {  
            public string SendSetData;//发送的数据  
            public bool? SendSetMode;//发送模式  
        }
      
        public MainWindow()
        {
            InitializeComponent();
        }
        private  void  check_com( )
        {
            ports = SerialPort.GetPortNames();//获取可用串口  
            if (ports.Length > 0)//ports.Length > 0说明有串口可用  
            {
                for (int i = 0; i < ports.Length; i++)
                {
                    ckh.Items.Add(ports[i]);//下拉控件里添加可用串口  
                }

            }
            else//未检测到串口  
            {
                jsc.AppendText(DateTime.Now.ToString("hh:mm:ss") + ":     无可用串口！"+Environment .NewLine );
            }
        }
        private void window_load(object sender, RoutedEventArgs e)
        {
  
            //↓↓↓↓↓↓↓↓↓可用串口下拉控件↓↓↓↓↓↓↓↓↓
            jsc.Text = "";
            check_com();
            btl.Items.Clear();
            IList<customer> rateList = new List<customer>();//可用波特率集合  
            rateList.Add(new customer() { BaudRate = "1200" });
            rateList.Add(new customer() { BaudRate = "2400" });
            rateList.Add(new customer() { BaudRate = "4800" });
            rateList.Add(new customer() { BaudRate = "9600" });
            rateList.Add(new customer() { BaudRate = "14400" });
            rateList.Add(new customer() { BaudRate = "19200" });
            rateList.Add(new customer() { BaudRate = "28800" });
            rateList.Add(new customer() { BaudRate = "38400" });
            rateList.Add(new customer() { BaudRate = "57600" });
            rateList.Add(new customer() { BaudRate = "115200" });
            btl.ItemsSource = rateList;
            btl.DisplayMemberPath = "BaudRate";
            btl.SelectedValuePath = "BaudRate"; 

            //↓↓↓↓↓↓↓↓↓校验位下拉控件↓↓↓↓↓↓↓↓↓  
            IList<customer> comParity = new List<customer>();//可用校验位集合  
            comParity.Add(new customer() { Parity = "None", ParityValue = "0" });
            comParity.Add(new customer() { Parity = "Odd", ParityValue = "1" });
            comParity.Add(new customer() { Parity = "Even", ParityValue = "2" });
            comParity.Add(new customer() { Parity = "Mark", ParityValue = "3" });
            comParity.Add(new customer() { Parity = "Space", ParityValue = "4" });
            jyw.ItemsSource = comParity;
            jyw.DisplayMemberPath = "Parity";
            jyw.SelectedValuePath = "ParityValue";
            //↑↑↑↑↑↑↑↑↑校验位下拉控件↑↑↑↑↑↑↑↑↑  

            //↓↓↓↓↓↓↓↓↓数据位下拉控件↓↓↓↓↓↓↓↓↓  
            IList<customer> dataBits = new List<customer>();//数据位集合  
            dataBits.Add(new customer() { Dbits = "8" });
            dataBits.Add(new customer() { Dbits = "7" });
            dataBits.Add(new customer() { Dbits = "6" });
           sjw.ItemsSource = dataBits;
           sjw.SelectedValuePath = "Dbits";
           sjw.DisplayMemberPath = "Dbits";
            //↑↑↑↑↑↑↑↑↑数据位下拉控件↑↑↑↑↑↑↑↑↑  

            //↓↓↓↓↓↓↓↓↓停止位下拉控件↓↓↓↓↓↓↓↓↓  
            IList<customer> stopBits = new List<customer>();//停止位集合  
            stopBits.Add(new customer() { Sbits = "1" });
            stopBits.Add(new customer() { Sbits = "1.5" });
            stopBits.Add(new customer() { Sbits = "2" });
            tzw.ItemsSource = stopBits;
            tzw.SelectedValuePath = "Sbits";
            tzw.DisplayMemberPath = "Sbits";
            //↑↑↑↑↑↑↑↑↑停止位下拉控件↑↑↑↑↑↑↑↑↑  

            //↓↓↓↓↓↓↓↓↓默认设置↓↓↓↓↓↓↓↓↓  
            btl.SelectedValue = "9600";//波特率默认设置9600  
            jyw.SelectedValue = "0";//校验位默认设置值为0，对应NONE  
            sjw.SelectedValue = "8";//数据位默认设置8位  
            tzw.SelectedValue = "1";//停止位默认设置1  
            ComPort.ReadTimeout = 8000;//串口读超时8秒  
            ComPort.WriteTimeout = 8000;//串口写超时8秒，在1ms自动发送数据时拔掉串口，写超时5秒后，会自动停止发送，如果无超时设定，这时程序假死  
            ComPort.ReadBufferSize = 1024;//数据读缓存  
            ComPort.WriteBufferSize = 1024;//数据写缓存  
            //↑↑↑↑↑↑↑↑↑默认设置↑↑↑↑↑↑↑↑↑  
            ComPort.DataReceived+=ComPort_DataReceived;
            autoSendTick.Tick += autoSendTick_Tick;
        

            
        }

        void autoSendTick_Tick(object sender, EventArgs e)
        {
            Send();
        }


void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
 	if (WaitClose) return;//如果正在关闭串口，则直接返回  
            if (recStaus)//如果已经开启接收  
            {  
                try  
                {  
                    Listening = true;////设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。  
                    Thread.Sleep(10);//发送和接收均为文本时，接收中为加入判断是否为文字的算法，发送你（C4E3），接收可能识别为C4,E3，可用在这里加延时解决  
                    string recData;//接收数据转码后缓存  
                    byte[] recBuffer = new byte[ComPort.BytesToRead];//接收数据缓存  
                    ComPort.Read(recBuffer, 0, recBuffer.Length);//读取数据  
                    recData = System.Text.Encoding.Default.GetString(recBuffer);//转码  
                    this.jsc.Dispatcher.Invoke(//WPF为单线程，此接收中断线程不能对WPF进行操作，用如下方法才可操作  
                    new Action(  
                         delegate  
                         {
                             recCount.Text = (Convert.ToInt32(recCount.Text) + recBuffer.Length).ToString();//接收数据字节数  
                             if (recModeCheck.IsChecked == false)//接收模式为ASCII文本模式  
                             {  
                                 jsc.Text += recData;//加显到接收区  
  
                             }  
                             else  
                             {  
                                 StringBuilder recBuffer16 = new StringBuilder();//定义16进制接收缓存  
                                 for (int i = 0; i < recBuffer.Length; i++)  
                                 {  
                                     recBuffer16.AppendFormat("{0:X2}" + " ", recBuffer[i]);//X2表示十六进制格式（大写），域宽2位，不足的左边填0。  
                                 }  
                                 jsc.Text += recBuffer16.ToString();//加显到接收区  
                             }
                             if (jsc.LineCount > 100) jsc.Text = "";
                             jsc.ScrollToEnd();
                             
                         }  
                    )  
                    );  
  
                }  
                finally  
                {  
                    Listening = false;//UI使用结束，用于关闭串口时判断，避免自动发送时拔掉串口，陷入死循环  
                }  
  
            }  
            else//暂停接收  
            {  
                ComPort.DiscardInBuffer();//清接收缓存  
            }  
  
  
}

        private void bt1_click(object sender, RoutedEventArgs e)
        {
            ckh.Items.Clear();
            check_com();
        }
          private void SetAfterClose()//成功关闭串口或串口丢失后的设置  
        {  
  
            openPort.Content = "打开串口";//按钮显示为“打开串口” 
            ComPortIsOpen = false;//串口状态设置为关闭状态  
            sendBtn.IsEnabled = false;//失能发送数据按钮  
            ckh.IsEnabled = true;//使能可用串口控件  
            btl.IsEnabled = true;//使能可用波特率下拉控件  
            jyw.IsEnabled = true;//使能可用校验位下拉控件  
            sjw.IsEnabled = true;//使能数据位下拉控件  
            tzw.IsEnabled = true;//使能停止位下拉控件  
        } 
        /// <summary>
        ///  模拟 Winfrom 中 Application.DoEvents() 详见 http://www.silverlightchina.net/html/study/WPF/2010/1216/4186.html?1292685167  
        /// </summary>
         public static class DispatcherHelper  
        {  
            [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]  
            public static void DoEvents()  
            {  
                DispatcherFrame frame = new DispatcherFrame();  
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrames), frame);  
                try { Dispatcher.PushFrame(frame); }  
                catch (InvalidOperationException) { }  
            }  
            private static object ExitFrames(object frame)  
            {  
                ((DispatcherFrame)frame).Continue = false;  
                return null;  
            }  
        }  
           private void SetComLose()//成功关闭串口或串口丢失后的设置  
        {  
            autoSendTick.Stop();//串口丢失后要关闭自动发送    
            WaitClose = true;//;//激活正在关闭状态字，用于在串口接收方法的invoke里判断是否正在关闭串口  
            while (Listening)//判断invoke是否结束  
            {  
                DispatcherHelper.DoEvents(); //循环时，仍进行等待事件中的进程，该方法为winform中的方法，WPF里面没有，这里在后面自己实现  
            }  
            MessageBox.Show("串口已丢失");  
            WaitClose = false;//关闭正在关闭状态字，用于在串口接收方法的invoke里判断是否正在关闭串口  
            check_com();//刷新可用串口  
            SetAfterClose();//成功关闭串口或串口丢失后的设置  
        } 
        private void openport_click(object sender, RoutedEventArgs e)
        {
            
            if (ckh.SelectedValue == null)//先判断是否有可用串口  
            {  
                MessageBox.Show("无可用串口，无法打开!");  
                return;//没有串口，提示后直接返回  
            }  
            #region 打开串口  
            if (ComPortIsOpen == false)//ComPortIsOpen == false当前串口为关闭状态，按钮事件为打开串口  
            {  
                  
                try//尝试打开串口  
                {  
                    ComPort.PortName =ckh.SelectedValue.ToString();//设置要打开的串口  
                    ComPort.BaudRate = Convert.ToInt32(btl.SelectedValue);//设置当前波特率  
                    ComPort.Parity = (Parity)Convert.ToInt32(jyw.SelectedValue);//设置当前校验位  
                    ComPort.DataBits = Convert.ToInt32(sjw.SelectedValue);//设置当前数据位  
                    ComPort.StopBits = (StopBits)Convert.ToDouble(tzw.SelectedValue);//设置当前停止位                      
                    ComPort.Open();//打开串口  
                      
                }  
                catch//如果串口被其他占用，则无法打开  
                {  
                    MessageBox.Show("无法打开串口,请检测此串口是否有效或被其他占用！");  
                    check_com();//刷新当前可用串口  
                    return;//无法打开串口，提示后直接返回  
                }  
  
                //↓↓↓↓↓↓↓↓↓成功打开串口后的设置↓↓↓↓↓↓↓↓↓  
                openPort.Content = "关闭串口";//按钮显示改为“关闭按钮”   
                ComPortIsOpen = true;//串口打开状态字改为true  
                WaitClose = false;//等待关闭串口状态改为false                  
                sendBtn.IsEnabled = true;//使能“发送数据”按钮   
                ckh.IsEnabled = false;//失能可用串口控件  
                btl.IsEnabled = false;//失能可用波特率控件  
                jyw.IsEnabled = false;//失能可用校验位控件  
                sjw.IsEnabled = false;//失能可用数据位控件  
                tzw.IsEnabled = false;//失能可用停止位控件  
                //↑↑↑↑↑↑↑↑↑成功打开串口后的设置↑↑↑↑↑↑↑↑↑  

                if (autoSendCheck.IsChecked == true)//如果打开前，自动发送控件就被选中，则打开串口后自动开始发送数据  
                {
                    autoSendTick.Interval = TimeSpan.FromMilliseconds(Convert.ToInt32(Time.Text));//设置自动发送间隔  
                    autoSendTick.Start();//开启自动发送  
                }  
  
             }  
            #endregion  
            #region 关闭串口  
            else//ComPortIsOpen == true,当前串口为打开状态，按钮事件为关闭串口  
            {                  
                try//尝试关闭串口  
                {  
                    autoSendTick.Stop();//停止自动发送  
                    autoSendCheck.IsChecked = false;//停止自动发送控件改为未选中状态  
                    ComPort.DiscardOutBuffer();//清发送缓存  
                    ComPort.DiscardInBuffer();//清接收缓存  
                    WaitClose = true;//激活正在关闭状态字，用于在串口接收方法的invoke里判断是否正在关闭串口  
                    while (Listening)//判断invoke是否结束  
                    {  
                        DispatcherHelper.DoEvents(); //循环时，仍进行等待事件中的进程，该方法为winform中的方法，WPF里面没有，这里在后面自己实现  
                    }  
                    ComPort.Close();//关闭串口  
                    WaitClose = false;//关闭正在关闭状态字，用于在串口接收方法的invoke里判断是否正在关闭串口  
                    SetAfterClose();//成功关闭串口或串口丢失后的设置  
                }  
                  
                catch//如果在未关闭串口前，串口就已丢失，这时关闭串口会出现异常  
                {  
                    if (ComPort.IsOpen == false)//判断当前串口状态，如果ComPort.IsOpen==false，说明串口已丢失  
                    {  
                        SetComLose();  
                    }  
                    else//未知原因，无法关闭串口  
                    {  
                        MessageBox.Show("无法关闭串口，原因未知！");  
                        return;//无法关闭串口，提示后直接返回  
                    }  
                }  
            }  
            #endregion  
  
        }
        void UIAction(Action action)//在主线程外激活线程方法  
        {
            System.Threading.SynchronizationContext.SetSynchronizationContext(new System.Windows.Threading.DispatcherSynchronizationContext(App.Current.Dispatcher));
            System.Threading.SynchronizationContext.Current.Post(_ => action(), null);
        }  
        private void ComSend(Object obj)//发送数据 独立线程方法 发送数据时UI可以响应  
        {

            lock (this)//由于send()中的if (Sending == true) return，所以这里不会产生阻塞，如果没有那句，多次启动该线程，会在此处排队  
            {
                Sending = true;//正在发生状态字  
                byte[] sendBuffer = null;//发送数据缓冲区  
                string sendData = SendSet.SendSetData;//复制发送数据，以免发送过程中数据被手动改变  
                if (SendSet.SendSetMode == true)//16进制发送  
                {
                    try //尝试将发送的数据转为16进制Hex  
                    {
                        sendData = sendData.Replace(" ", "");//去除16进制数据中所有空格  
                        sendData = sendData.Replace("\r", "");//去除16进制数据中所有换行  
                        sendData = sendData.Replace("\n", "");//去除16进制数据中所有换行  
                        if (sendData.Length == 1)//数据长度为1的时候，在数据前补0  
                        {
                            sendData = "0" + sendData;
                        }
                        else if (sendData.Length % 2 != 0)//数据长度为奇数位时，去除最后一位数据  
                        {
                            sendData = sendData.Remove(sendData.Length - 1, 1);
                        }

                        List<string> sendData16 = new List<string>();//将发送的数据，2个合为1个，然后放在该缓存里 如：123456→12,34,56  
                        for (int i = 0; i < sendData.Length; i += 2)
                        {
                            sendData16.Add(sendData.Substring(i, 2));
                        }
                        sendBuffer = new byte[sendData16.Count];//sendBuffer的长度设置为：发送的数据2合1后的字节数  
                        for (int i = 0; i < sendData16.Count; i++)
                        {
                            sendBuffer[i] = (byte)(Convert.ToInt32(sendData16[i], 16));//发送数据改为16进制  
                        }
                    }
                    catch //无法转为16进制时，出现异常  
                    {
                        UIAction(() =>
                        {
                  
                            autoSendTick.Stop();//关闭自动发送  
                            MessageBox.Show("请输入正确的16进制数据");
                        });

                        Sending = false;//关闭正在发送状态  
                        _ComSend.Abort();//终止本线程  
                        return;//输入的16进制数据错误，无法发送，提示后返回    
                    }

                }
                else //ASCII码文本发送  
                {
                    sendBuffer = System.Text.Encoding.Default.GetBytes(sendData);//转码  
                }
                try//尝试发送数据  
                {//如果发送字节数大于1000，则每1000字节发送一次  
                    int sendTimes = (sendBuffer.Length / 1000);//发送次数  
                    for (int i = 0; i < sendTimes; i++)//每次发生1000Bytes  
                    {
                        ComPort.Write(sendBuffer, i * 1000, 1000);//发送sendBuffer中从第i * 1000字节开始的1000Bytes  
                        UIAction(() =>//激活UI  
                        {
                            sendCount.Text = (Convert.ToInt32(sendCount.Text) + 1000).ToString();//刷新发送字节数  
                        });
                    }
                    if (sendBuffer.Length % 1000 != 0)//发送字节小于1000Bytes或上面发送剩余的数据  
                    {
                        ComPort.Write(sendBuffer, sendTimes * 1000, sendBuffer.Length % 1000);
                        UIAction(() =>
                        {
                            sendCount.Text = (Convert.ToInt32(sendCount.Text) + sendBuffer.Length % 1000).ToString();//刷新发送字节数  
                        });
                    }


                }
                catch//如果无法发送，产生异常  
                {
                    UIAction(() =>//激活UI  
                    {
                        if (ComPort.IsOpen == false)//如果ComPort.IsOpen == false，说明串口已丢失  
                        {
                            SetComLose();//串口丢失后的设置  
                        }
                        else
                        {
                            MessageBox.Show("无法发送数据，原因未知！");
                        }
                    });
                }
                //sendScrol.ScrollToBottom();//发送数据区滚动到底部  
                Sending = false;//关闭正在发送状态  
                _ComSend.Abort();//终止本线程  
            }

        }
        void Send()//发送数据，分为多线程方式和单线程方式  
        {
            if (Sending == true) return;//如果当前正在发送，则取消本次发送，本句注释后，可能阻塞在ComSend的lock处  
            _ComSend = new Thread(new ParameterizedThreadStart(ComSend)); //new发送线程  
            SendSet.SendSetData = fsc.Text ;//发送数据线程传递参数的结构体--发送的数据  
            SendSet.SendSetMode = sendModeCheck.IsChecked; //发送数据线程传递参数的结构体--发送方式  
            _ComSend.Start(SendSet);//发送线程启动  
        }
        private void windows_closed(object sender, EventArgs e)
        {
            Application.Current.Shutdown();//先停止线程,然后终止进程.  
            Environment.Exit(0);//直接终止进程. 
        }

        private void sendBtn_Click(object sender, RoutedEventArgs e)
        {
            Send();
        }

        private void jsc_dbclick(object sender, MouseButtonEventArgs e)
        {
            jsc.Text = "";
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            recCount.Text = "0";
            sendCount.Text = "0";
        }

        private void autosend_Checked(object sender, RoutedEventArgs e)
        {

            if (autoSendCheck.IsChecked == true && ComPort.IsOpen == true)//如果当前状态为开启自动发送且串口已打开，则开始自动发送  
            {
                autoSendTick.Interval = TimeSpan.FromMilliseconds(Convert.ToInt32(Time.Text));//设置自动发送间隔  
                autoSendTick.Start();//开始自动发送定时器  
            }
            else//点击之前为开启自动发送状态，点击后关闭自动发送  
            {
                autoSendTick.Stop();//关闭自动发送定时器  
            } 
        }
        #region 折线图
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="lsTime"></param>
        /// <param name="cherry"></param>
        /// <param name="pineapple"></param>
        /// 
    
        private List<Int16> xnum = new List<Int16>();
        private List<Int16> ynum = new List<Int16>();
        public void CreateChartSpline()
        {
            //创建一个图标
            Chart chart = new Chart();
           
            //设置图标的宽度和高度
            chart.Width = CS1.ActualWidth;
            chart.Height =CS1.ActualHeight;
            chart.Margin = new Thickness(100, 5, 10, 5);
            //是否启用打印和保持图片
            chart.ToolBarEnabled = false;

            //设置图标的属性
            chart.ScrollingEnabled = false;//是否启用或禁用滚动
            chart.View3D = false ;//3D效果显示

            //创建一个标题的对象
            Title title = new Title();

            //设置标题的名称
            title.Text = "接收到的信息";
            title.Padding = new Thickness(0, 10, 5, 0);

            //向图标添加标题
            chart.Titles.Add(title);

            //初始化一个新的Axis
            Axis xaxis = new Axis();
            //设置Axis的属性
            xaxis.Suffix = "次";
            //图表的X轴坐标按什么来分类，如时分秒
            xaxis.IntervalType = IntervalTypes.Auto;
            //图表的X轴坐标间隔如2,3,20等，单位为xAxis.IntervalType设置的时分秒。
            xaxis.Interval = 1;
            //给图标添加Axis            
            chart.AxesX.Add(xaxis);

            Axis yAxis = new Axis();
            //设置图标中Y轴的最小值永远为0           
            yAxis.AxisMinimum = 0;
            //设置图表中Y轴的后缀          
            yAxis.Suffix = "V";
            chart.AxesY.Add(yAxis);
            //将生产的图表增加到Grid，然后通过Grid添加到上层Grid.

            // 创建一个新的数据线。               
            DataSeries dataSeries = new DataSeries();
            // 设置数据线的格式。               
            dataSeries.LegendText = "通道1";
            dataSeries.RenderAs = RenderAs.Spline;//折线图
            dataSeries.XValueType = ChartValueTypes.Auto;

            DataPoint dataPoint;
            for (int i = 0; i < xnum.Count; i++)
            {
                // 创建一个数据点的实例。                   
                dataPoint = new DataPoint();
                // 设置X轴点                    
                dataPoint.XValue = xnum[i];
                //设置Y轴点                   
                dataPoint.YValue =ynum[i];
                dataPoint.MarkerSize = 8;
                //dataPoint.Tag = tableName.Split('(')[0];
                //设置数据点颜色                  
                // dataPoint.Color = new SolidColorBrush(Colors.LightGray);                   
                //添加数据点                   
                dataSeries.DataPoints.Add(dataPoint);
            }

           chart.Series.Add(dataSeries);
           CS1.Children.Add(chart);

        }
        #endregion
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            for (Int16 i = 0; i < 15; i++)
            {
                xnum.Add(i);
                ynum.Add(i);
            
            }
                CreateChartSpline();
        }
 
  
        }
    }

